﻿using Shop.Collect.Linq;
using Shop.Model.DB;
using Shop.RemoteModel.LogisticsConfig.Model;
using Shop.Repository;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Shop.Collect.lmpl
{
    internal class LogisticsConfigCollect : ILogisticsConfigCollect
    {
        private readonly ILogisticsConfigRepository _Repository;

        public LogisticsConfigCollect (ILogisticsConfigRepository repository)
        {
            this._Repository = repository;
        }
        public LogisticsPrice CalculatePrice (CalculateLogistics param)
        {
            LogisticsConfigDto[] dtos = this._Repository.GetAreaConfig(param.TemplateId, param.AreaId);
            if (dtos.IsNull())
            {
                throw new ErrorException("shop.no.config.logistics");
            }
            LogisticsConfigDto dto = dtos.Where(c => c.CheckIsUsable(param)).OrderBy(a => a.Sort()).FirstOrDefault();
            if (dto == null)
            {
                throw new ErrorException("shop.no.config.logistics");
            }
            return new LogisticsPrice
            {
                Show = dto.GetLogisticsShow(),
                Price = dto.Calculate(param)
            };
        }
        public Result Get<Result> (long id) where Result : class
        {
            return this._Repository.Get<Result>(id);
        }
        public DBLogisticsConfig Get (long id)
        {
            return this._Repository.Get(id);
        }
        public long Add (LogisticsConfigAdd add)
        {
            if (this._Repository.IsExist(c => c.TemplateId == add.TemplateId && c.AreaId == add.AreaId))
            {
                throw new Exception("shop.logistics.config.repeat");
            }
            return this._Repository.Add(add);
        }
        public bool Set (DBLogisticsConfig config, LogisticsConfigSet set)
        {
            if (config.IsEnable)
            {
                throw new Exception("shop.logistics.config.already.enable");
            }
            return this._Repository.Update(config, set);
        }
        public Result[] Gets<Result> (LQueryParam query) where Result : class, new()
        {
            return this._Repository.Gets<Result>(query);
        }
        public Result[] Query<Result> (LQueryParam query, IBasicPage paging, out int count) where Result : class
        {
            return this._Repository.Query<Result>(query, paging, out count);
        }
        public void Delete (DBLogisticsConfig config)
        {
            if (config.IsEnable)
            {
                throw new Exception("shop.logistics.config.already.enable");
            }
            this._Repository.Delete(config.Id);
        }
        public void Clear (long templateId)
        {
            long[] ids = this._Repository.Gets(a => a.TemplateId == templateId, a => a.Id);
            if (ids.IsNull())
            {
                return;
            }
            this._Repository.Delete(ids);
        }
        public bool SetIsEnable (DBLogisticsConfig config, bool enable)
        {
            if (config.IsEnable == enable)
            {
                return false;
            }
            this._Repository.SetIsEnable(config.Id, enable);
            return true;
        }
    }
}
